//
//  SDHTTPRequestOperation.m
//  SKinDiary
//
//  Created by pcyang on 16/6/26.
//  Copyright © 2016年 tencent. All rights reserved.
//

#import "SDHTTPRequestOperation.h"
#import "SDJSON.h"

#define kNetworkLatencyReportSampling 10

@interface AFURLConnectionOperation ()
@property (readwrite, nonatomic, strong) NSError *error;
@property (readwrite, nonatomic, strong) NSURLRequest *request;
@property (readwrite, nonatomic, strong) NSRecursiveLock *lock;
- (void)finish;
- (void)operationDidStart;
@end

@interface SDHTTPRequestOperation ()
@property (nonatomic, strong, readwrite) id parsedObject;
@property (readwrite, nonatomic, strong) NSDate* startDate;
@property (nonatomic,assign,readwrite)   NSTimeInterval loadingTimeInterval;
@property (nonatomic,strong)             NSDate         *preOperatingDate;
@end

@implementation SDHTTPRequestOperation
- (void)clearDelegatesAndCancel
{
    self.objectParserBlock = nil;
    self.completionBlock = nil;
    [self cancel];
}

- (void)clearDelegates
{
    self.objectParserBlock = nil;
    self.completionBlock = nil;
}

- (void)buildRequestHeaders
{
    static NSMutableDictionary* defaultHeaders = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        defaultHeaders = [NSMutableDictionary dictionaryWithCapacity:10];
        
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"
        // User-Agent Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43
        NSString *userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], (__bridge id)CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleVersionKey) ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] ? [[UIScreen mainScreen] scale] : 1.0f)];
#pragma clang diagnostic pop
        if (userAgent)
        {
            if (![userAgent canBeConvertedToEncoding:NSASCIIStringEncoding])
            {
                NSMutableString *mutableUserAgent = [userAgent mutableCopy];
                CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, kCFStringTransformToLatin, false);
                userAgent = mutableUserAgent;
            }
            [defaultHeaders setObject:userAgent forKey:@"User-Agent"];
        }
//        
//        NSString* sizeInfo = [NSString stringWithFormat:@"%@;%.4f",NSStringFromCGSize([UIScreen screenSize]), [UIScreen mainScreen].scale];
//        [defaultHeaders setObject:sizeInfo forKey:@"DeviceScreen"];
//        
//        NSString* version = [[NSBundle mainBundle]objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
//        [defaultHeaders setObject:version forKey:@"AppVersion"];
//        
//        NSString* identifier = [[NSBundle mainBundle]bundleIdentifier];
//        [defaultHeaders setObject:identifier forKey:@"AppBundleID"];
        
      //  [defaultHeaders setObject:@"gzip, deflate" forKey:@"Accept-Encoding"];
       // [defaultHeaders setObject:@"gzip" forKey:@"Content-Encoding"];
    });
    
    NSMutableURLRequest* request = [self.request mutableCopy];
//    [defaultHeaders enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
//        [request setValue:obj forHTTPHeaderField:key];
//    }];
    
    //    NSMutableArray* allCookies = [NSMutableArray arrayWithCapacity:5];
    //    if(_isSendCookies && [[SDWXLogIn sharedInstance] isLoggedIn] )
    //    {
    //        NSArray *cookies = [[SDWXLogIn sharedInstance] getCookies];
    //        if( CHECK_VALID_ARRAY(cookies) )
    //            [allCookies addObjectsFromArray:cookies];
    //    }
    //
    //    NSString *cookieHeader = nil;
    //    for (NSHTTPCookie *cookie in allCookies)
    //    {
    //        if (!cookieHeader)
    //        {
    //            cookieHeader = [NSString stringWithFormat: @"%@=%@",[cookie name],[cookie value]];
    //        }
    //        else
    //        {
    //            cookieHeader = [NSString stringWithFormat: @"%@; %@=%@",cookieHeader,[cookie name],[cookie value]];
    //        }
    //    }
    
    __block NSMutableString *cookieHeader = nil;
    if (_requestCookies && _requestCookies.count>0)
    {
        [_requestCookies enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop)
         {
//             if (!cookieHeader)
//             {
//                 cookieHeader = [NSMutableString stringWithFormat: @"%@=%@", getShowString(key), getShowString(obj)];
//             }
//             else
//             {
//                 [cookieHeader appendFormat:@"; %@=%@", getShowString(key), getShowString(obj)];
//             }
             [defaultHeaders setObject:getShowString(obj) forKey:getShowString(key)];
         }];
    }
    
//    if(cookieHeader)
//    {
//        [request setValue:cookieHeader forHTTPHeaderField:@"Cookie"];
//        request.HTTPShouldHandleCookies = YES;
//    }
    
        [request setAllHTTPHeaderFields:defaultHeaders];
    self.request = request;
}

- (void)start
{
    [self.lock lock];
    [self buildRequestHeaders];
    [self.lock unlock];
    
    [super start];
}

- (void)operationDidStart
{
    self.startDate = [NSDate date];
    [super operationDidStart];
}

- (void)operationDidFinish
{
    [self.lock lock];
    
    if( self.error == nil && self.responseData )
    {
        NSError* error = nil;
        if(self.jsonParsed)self.parsedObject = [self.responseData parsedJSONObjectWithError:&error];
        else self.parsedObject = self.responseData;
        
        if( self.objectParserBlock )
            self.parsedObject = self.objectParserBlock(self.parsedObject,&error);
        
        self.error = error;
    }
    
    [self.lock unlock];
    
    [super finish];
    
    if( CHECK_VALID_STRING(self.interfaceIdentifier) && self.shouldReportNetworkLatency )
    {
        //lenahe begin
        //        __weak SDHTTPRequestOperation* weakSelf = self;
        //        dispatch_async(dispatch_get_main_queue(), ^{
        //
        //
        //                         __strong SDHTTPRequestOperation* strongSelf = weakSelf;
        //                        [QSBossReporter reportServerInterface:strongSelf.interfaceIdentifier timeInterval:strongSelf.loadingTimeInterval error:strongSelf.error];
        //        });
        //lenahe end
    }
    
}

- (void)finish {
    self.loadingTimeInterval = [[NSDate date]timeIntervalSinceDate:self.startDate];
    [self performSelector:@selector(operationDidFinish) withObject:nil afterDelay:0.0];
}

- (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                              failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
    // completionBlock is manually nilled out in AFURLConnectionOperation to break the retain cycle.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-retain-cycles"
#pragma clang diagnostic ignored "-Wgnu"
    self.completionBlock = ^{
        if (self.error) {
            if (failure) {
                dispatch_async(self.failureCallbackQueue ?: dispatch_get_main_queue(), ^{
                    failure(self, self.error);
                });
            }
        } else {
            if (success) {
                dispatch_async(self.successCallbackQueue ?: dispatch_get_main_queue(), ^{
                    success(self, self.parsedObject);
                });
            }
        }
    };
#pragma clang diagnostic pop
}


- (NSURLRequest *)connection:(NSURLConnection *)connection
             willSendRequest:(NSURLRequest *)request
            redirectResponse:(NSURLResponse *)redirectResponse
{
    //    NSString* dns = [connection.currentRequest.URL host]; //===权衡之下，上报不能增加程序负担，因此去掉域名解析
    //    NSString* ip = [SDDNSResolve ipFromDNSName:dns];
    //    if(nil==ip)
    //        [SDDNSResolve startDNSResolveForDNSName:dns];
    
    _kcgi = [[[request URL] absoluteURL] relativePath];
    _kdomain = [[request URL] host];
    
    NSDate *curDate = [NSDate date];
    
    if(_startDate)
        _kconn_time = [curDate timeIntervalSinceDate:_startDate];
    
    _preOperatingDate = curDate;
    
    return [super connection:connection willSendRequest:request redirectResponse:redirectResponse];
}


//- (void)connection:(NSURLConnection __unused *)connection
//didReceiveResponse:(NSURLResponse *)response
//{
//    [super connection:connection didReceiveResponse:response];
//}
//
//- (void)connection:(NSURLConnection __unused *)connection
//    didReceiveData:(NSData *)data
//{
//    [super connection:connection didReceiveData:data];
//}

- (void)connectionDidFinishLoading:(NSURLConnection __unused *)connection
{
    [super connectionDidFinishLoading:connection];
    
    if(_preOperatingDate)
        _ktrans_time = [[NSDate date] timeIntervalSinceDate:_preOperatingDate];
    
    _kdata_len = [self.responseData length];
}

- (void)connection:(NSURLConnection __unused *)connection
  didFailWithError:(NSError *)error
{
    [super connection:connection didFailWithError:error];
    
    if(_preOperatingDate)
        _ktrans_time = [[NSDate date] timeIntervalSinceDate:_preOperatingDate];
    
    _kdata_len = 0;
}
@end

